﻿// --------------
// 作者:Vitity
// --------------

using NICWebApi.Extensions.RESTfulResult.Providers;

namespace NICWebApi.Extensions.RESTfulResult.Filter;

/// <summary>
/// 全局异常过滤器
/// 统一处理应用程序中的异常，并返回标准化的响应
/// </summary>
public class ExceptionFilter : IAsyncExceptionFilter
{
    private readonly IUnifyResultProvider _resultProvider;

    /// <summary>
    /// 初始化异常过滤器
    /// </summary>
    /// <param name="resultProvider">结果提供器</param>
    public ExceptionFilter(
        IUnifyResultProvider resultProvider)
    {
        _resultProvider = resultProvider ?? throw new ArgumentNullException(nameof(resultProvider));
    }

    /// <summary>
    /// 处理异常
    /// </summary>
    /// <param name="context">异常上下文</param>
    public async Task OnExceptionAsync(ExceptionContext context)
    {
        if (context == null)
        {
            throw new ArgumentNullException(nameof(context));
        }

        // 如果异常已经被处理，则不再处理
        if (context.ExceptionHandled)
        {
            return;
        }

        // 获取异常信息
        var exception = context.Exception;
        var errorMessage = GetErrorMessage(exception);

        // 处理异常并返回结果
        context.Result = await HandleExceptionAsync(context, exception, errorMessage);
        context.ExceptionHandled = true;
    }

    /// <summary>
    /// 获取异常的错误信息
    /// </summary>
    private string GetErrorMessage(Exception exception)
    {
        if (exception == null)
        {
            return "发生未知错误";
        }

        // 获取最内层异常的信息
        var innerException = exception;
        while (innerException.InnerException != null)
        {
            innerException = innerException.InnerException;
        }

        return innerException.Message;
    }

    /// <summary>
    /// 处理异常并返回结果
    /// </summary>
    private async Task<IActionResult> HandleExceptionAsync(
        ExceptionContext context,
        Exception exception,
        string errorMessage)
    {
        // 根据异常类型返回不同的结果
        return exception switch
        {
            UnauthorizedAccessException => _resultProvider.OnException(context, "未授权的访问"),
            ArgumentException => _resultProvider.OnException(context, "参数错误: " + errorMessage),
            InvalidOperationException => _resultProvider.OnException(context, "操作无效: " + errorMessage),
            _ => _resultProvider.OnException(context, "服务器内部错误: " + errorMessage)
        };
    }
}